import { _decorator, Component, Size, size, Sprite, SpriteFrame, UITransform, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

/** 砖块的设计尺寸 */
const TILE_DESIGN_SIZE = {
	box: size(119, 116),
	view: size(119, 135)
}

@ccclass('Tile')
export class Tile extends Component {
	@property(UITransform)
	private uitrans: UITransform = null;
	@property(Sprite)
	private sprite: Sprite = null;
	@property(UITransform)
	private ui_sprite: UITransform = null;
	@property(UITransform)
	private ui_shade: UITransform = null;

	private va_sprite: mtec.cc.VecAssist;
	private va_shade: mtec.cc.VecAssist;

	private id: string;
	private light: boolean = false;
	private block_size = TILE_DESIGN_SIZE.box.clone();

	public get ID(){
		return this.id;
	}
	public get Light(){
		return this.light;
	}
	public get active(){
		return this.node && this.node.active && this.node.isValid;
	}
	public get width(){
		return this.block_size.width;
	}
	public get height(){
		return this.block_size.height;
	}

	protected onLoad(): void {
		this.va_sprite = new mtec.cc.VecAssist(this.ui_sprite.node);
		this.va_shade = new mtec.cc.VecAssist(this.ui_shade.node);
	}

	protected onEnable(){
		this.updateSize();
		this.updateSprite();
		this.ui_shade.node.active = !this.Light;
	}

	public init(id: string, width: Size|number, height?: number){
		this.setID(id);
		this.setSize(width, height);
	}

	public setLight(light: boolean){
		this.light = light;

		if(this.active){
			this.ui_shade.node.active = !light;
		}
	}

	public setSize(width: Size|number, height?: number){
		if(width instanceof Size){
			height = width.height;
			width = width.width;
		}else if(!(width>0)){
			width = TILE_DESIGN_SIZE.box.width;
		}

		if(!(height>0)){
			height = width;
		}

		let scale = Math.min(width / TILE_DESIGN_SIZE.box.width, height / TILE_DESIGN_SIZE.box.height);
		this.block_size = size(TILE_DESIGN_SIZE.box.width * scale, TILE_DESIGN_SIZE.box.height * scale);

		this.updateSize();
	}

	public setID(id: string){
		this.id = id;
		this.updateSprite();
	}

	private updateSize(){
		if(!this.active){
			return void 0;
		}

		this.uitrans.setContentSize(this.block_size);

		let scale = this.block_size.width / TILE_DESIGN_SIZE.box.width;

		[this.ui_sprite, this.ui_shade]
		.forEach(ui=> ui.setContentSize(
			TILE_DESIGN_SIZE.view.width * scale,
			TILE_DESIGN_SIZE.view.height * scale
		));

		(<const>[
			[this.ui_sprite, this.va_sprite],
			[this.ui_shade, this.va_shade],
		]).forEach(([ui, va])=>{
			ui.node.setPosition(va.getPosition('center', 'top'));
		});
	}

	private updateSprite(){
		if(!this.active){
			return void 0;
		}

		if(this.id && this.id!=this.sprite.spriteFrame.name){
			let sframe = Tile.getIconSpriteFrame(this.id);
			this.sprite.spriteFrame = sframe;
		}

		let scale = this.block_size.width / TILE_DESIGN_SIZE.box.width;

		this.ui_sprite.setContentSize(TILE_DESIGN_SIZE.view.width * scale, TILE_DESIGN_SIZE.view.height * scale);
		this.ui_sprite.node.setPosition(this.va_sprite.getPosition('center', 'top'));
	}

	/**
	 * 将砖块的位置转换为视图坐标
	 * @param position
	 * @param out
	 */
	public convertToViewSpaceAR(position: Vec3, out?: Vec3){

		if(!out){
			out = position.clone();
		}else{
			out.set(position);
		}

		out.subtract(this.ui_sprite.node.position);

		return out;
	}

	private static icon_smap: Map<string, SpriteFrame>;

	private static getIconSpriteFrame(name: string){
		let sframe: SpriteFrame;

		if(Tile.icon_smap){
			sframe = Tile.icon_smap.get(name);
		}

		if(!sframe){
			console.warn(`Icon sprite frame "<< ${name} >>" not found!`, Tile.icon_smap);
			sframe = SpriteFrame.createWithImage(new Image(100, 100));
		}

		return sframe;
	}

	public static initIconSpriteFrame(sprite_list: SpriteFrame[]){
		if(Tile.icon_smap){
			return void 0;
		}

		Tile.icon_smap = new Map(sprite_list.map(s=>[s.name, s]));
	}

	/**
	 * 计算视图的尺寸
	 * @param width
	 * @param height
	 */
	public static calculateViewSize(width: number|Size, height: number){
		if(width instanceof Size){
			height = width.height;
			width = width.width;
		}else if(!(width>0)){
			width = TILE_DESIGN_SIZE.view.width;
		}

		if(!(height>0)){
			height = width;
		}

		let scale = Math.min(width / TILE_DESIGN_SIZE.view.width, height / TILE_DESIGN_SIZE.view.height);

		let [box, view] = [TILE_DESIGN_SIZE.box, TILE_DESIGN_SIZE.view].map(s=>size(s.width * scale, s.height * scale));

		return {box, view};
	}

	/**
	 * 计算砖块的尺寸
	 * @param width
	 * @param height
	 */
	public static calculateBoxSize(width: number|Size, height: number){
		if(width instanceof Size){
			height = width.height;
			width = width.width;
		}else if(!(width>0)){
			width = TILE_DESIGN_SIZE.view.width;
		}

		if(!(height>0)){
			height = width;
		}

		let scale = Math.min(width / TILE_DESIGN_SIZE.box.width, height / TILE_DESIGN_SIZE.box.height);

		let [box, view] = [TILE_DESIGN_SIZE.box, TILE_DESIGN_SIZE.view].map(s=>size(s.width * scale, s.height * scale));

		return {box, view};

	}
}

